home *** CD-ROM | disk | FTP | other *** search
- █████████████▐ Ex-planed (;)) ███▐ ██████████████ ██████████████
- █████████████▐ ███▐ ██████ ██████
- ███▐ ███▐ ███▐ ███▐ █▀▄ █▀▄ █▀▄ ██████ ██████
- ███▐ ███▐ ███▐ ███▐ ▄█ █ █ █ █████ █████
- ███▐ ███▐ ███▐ ███▐ ▄ █ █▀ █ █ ████ ████
- ███▐ ███▐ ███▐ ███▐ ▀▀ ▀▀ ▀▀ ████ ████
- ███▐ ███▐ ███▐ ███▐ █ ▄ █▀▄ █▀▄ ██████
- ███▐ ███▐ ███▐ ▀▄█ █ █ █ █ ████
- ███▐ ███▐ ████████▐ ████████▐ █████▐ █ █ █ █ █ ████
- ███▐ ███▐ ████████▐ ████████▐ █████▐ ▀ ▀▀ ▀▀ ██████
- ███▐ ███▐ ███▐ ███▐ ███▐ ███▐ ████ █▀▄ █▀ █▀ ████ ████
- ███▐ ███▐ ███▐ ███▐ ███▐ ███▐ █████▐ █ ▀▄ █▀▄ ████ ████
- ███▐ ███▐ ███▐ ███▐ ███▐ ███▐ █████▐ █▀ █ ▀▄█ █████ █████
- ███▐ ███▐ ███▐ ███▐ ███▐ ███▐ ████ ▀▀ ▀ ██████ ██████
- ███▐ ███▐ ████████▐ ████████▐ █████▐ ██████ ██████
- ███▐ ███▐ ████████▐ ████████▐ █████▐ ██████████████ ██████████████
- ───────────────────────────────═ The Bitripper ═────────────────────────────────
-
- Ok guys, for the re-bound. Here's The Bitripper bringing you, coders all over,
- _*THE*_ invitation to the so-called tweaked modi. Well, actually this is only
- describing the 320x400x256 mode, but there are enough trainers to cover the lack
- of this one. BTW, this one is only meant to correct some mistakes which I found
- through many trainers, it's not a complete guide on the VGA programming subject.
- If you want a complete guide, buy a good book (a thing with papers stuck inside
- a hard cover). E.g. Programmers Guide to the EGA/VGA, Richard E. Ferraro,
- PC Intern 4, or use some all-round hypertexts, e.g. HelpPC, Tech!Help.
-
- Assumptions: knowledge of ASM, color VGA card in possession, 16-bit programming,
- little knowledge of VGA registers and ports programming
-
- Enclosed in this package should be the following files:
-
- UNCHAIN.TXT - This textfile
- XMODE.ASM - Example code, changing to XMODE and displaying a 256 color
- picture two times
- PALETTE.INC - Palette for picture shown by XMODE.ASM (is included and must be
- in the same directory)
- PICTURE.INC - Picture shown by XMODE.ASM (is included and must be in the same
- directory)
- DESCRIPT.ION - 4DOS Description file
- MAKEFILE. - MakeFile for Borland's MAKE utility
- XMODE.EXE - Compiled and packed version of XMODE.ASM
- FILE_ID.DIZ - File ID for BBS's, please do not remove
-
-
- ┌──────────────────────────────────────────────────────────────────────────────┐
- │░▒▓█ INTRODUCTION █▓▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
- └──────────────────────────────────────────────────────────────────────────────┘
-
- Let me introduce you into my experience with learning about the so-called
- tweaked modi (hereafter: xmode).
-
- When I first started to have a look at the xmode, it was basically coz' many of
- other productions were using the xmode mainly due to it's higher resolutions.
- Everybody was using the xmode, so there had to be something very special about
- it, and I got very interested in learning every aspect of the xmode.
-
- I got myself a book (borrowed from a friend of mine). A very good book actually,
- the Programmers Guide to the EGA/VGA second edition of Richard E. Ferraro.
- In it, there was a total, bug-free description of each VGA register and the way
- each part of yar VGA card works. I used it as a reference while I was examining
- the xmode code of other programmers and while reading the trainers about the
- subject.
-
- I encountered some slight problems while implementing the ideas I got from all
- the different trainers. For example, I got myself running into the double-word
- modus over and over again because I was anxious to know every bit (literally!)
- of the code changing the normal BIOS mode 13h into xmode before I would use it
- (as I do with all the rest of the effects etc.).
-
- So, when my friend needed his book back, and I still hadn't found out what the
- double-word modus was about, there was some kind of disappointment.
-
- That was until I bought myself PC Intern 4, and started to read in it.
- Although, there are quite a few mistakes, even faults and don't mention errors
- in the book. With the help of some hypertexts and the PC Game Programmers
- Encyclopedia I finally found out what _*EXACTLY*_ this double-word modus
- was about.
-
- But hey, enough of this crap. Let's get ya all back to business with the xmode
- explanation.
-
- Press cursor down key when ready... ;)
-
-
- ┌──────────────────────────────────────────────────────────────────────────────┐
- │░▒▓█ BIOS MODE 13h vs. XMODE █▓▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
- └──────────────────────────────────────────────────────────────────────────────┘
-
- The xmode has (obviously) advantages above the BIOS mode. Unfortunately, it also
- has some disadvantages which must be taken into account when choosing which mode
- is going to be used. XMode is not all of the time recommended. I'll show you:
-
- Advantages for BIOS mode 13h:
- - Can address all pixels in one segment.
- - No need for handling the read/write plane coz' it's automatically selected for
- you (plane number is taken from the offset).
- - No need for more code to initialize, only one call to standard BIOS
- video interrupt.
-
- Disadvantages for BIOS mode 13h:
- - Only one page for displaying graphics, so no page-flipping can be performed in
- the VGA memory itself.
- - Low resolution, 320x200 (although it's actually 320x400, as you'll see l8ron).
- - 192 kB of VGA memory is wasted due to the easy accessibility.
-
-
- Advantages for XMODE:
- - Page flipping can be performed using the VGA memory.
- - Up to 4 pages can be used.
- - Any resolution can be set by programming the VGA registers directly.
- - Scrolling of large pictures is easier.
-
- Disadvantages for XMODE:
- - Every pixel read/write must be directed to one or more planes.
- - Extra code to initialize xmode.
-
-
- ┌──────────────────────────────────────────────────────────────────────────────┐
- │░▒▓█ VGA HARDWARE █▓▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
- └──────────────────────────────────────────────────────────────────────────────┘
-
- The VGA memory consists of four 64 kB planes (see them as large arrays).
- In normal BIOS - or 'chained' - mode, these planes are chained together
- so that an easy addressing is possible, eliminating the need of specifying each
- plane before writing to or reading from it. Planes are numbered from 0 to 3.
-
- For each offset you write to or read from, the two lowest bits of the offset
- are used to determine the plane to write to or read from. If, for example, you
- write a byte with value 0fh to offset 5h, what plane would it end up ?
- Well, take a look at the example:
-
- Offset 0005h = 0000 0000 0000 0101b
- ^^
- The lowest two bits of the offset address are 01b, which equals 1.
-
- Then, the offset is shifted two bits to the right to loose the plane bits.
-
- Offset 0001h = 0000 0000 0000 0001b
-
- To determine the offset within the given plane, the offset is shifted two bits
- to the left:
-
- Offset 0004h = 0000 0000 0000 0100b
-
- Thus, writing 0fh to offset 5h in the video memory area results in writing 0fh
- to plane 1 at offset 4h within that plane.
-
- When the BIOS mode is initialized, the memory looks like this (where the numbers
- in the different planes corresponds to the numbers in the video memory area):
-
- 0 319
- ┌───────────────────────────────────────────────────────────────────────────┐ 0
- │01234567 │
- │ │
- · ·
- · ·
- · ·
- │ │
- └───────────────────────────────────────────────────────────────────────────┘199
- Video memory area as 'seen' by the coder (this is actually also the VGA memory)
-
-
- Plane 3 ┌01234567─────────────────────────────────────────────────────┐
- (11b) │3░░░7░░░ │
- │ │
- │
- Plane 2 ┌01234567─────────────────────────────────────────────────────┐ │
- (10b) │2░░░6░░░ │ │
- │ │ │
- │ │
- Plane 1 ┌01234567─────────────────────────────────────────────────────┐ │ │
- (01b) │1░░░5░░░ │ │ │
- │ │ │ │
- │ │
- Plane 0 ┌01234567─────────────────────────────────────────────────────┐ │ │
- (00b) │0░░░4░░░ │ │ │
- │ │ │ │
- │ │ │
- │ │ │
- │ │ │
- │ │
- │ │
- │ │
- Real plane dividing in the memory of the VGA (chained mode, double-word mode)
-
- The '░' denotes an empty, unused byte. You see, for each four bytes in a plane,
- 3 bytes are not used. As each plane contains 320*200 bytes and there are four
- planes, there are 320*200*4 bytes = 256000 bytes total of which ¼ is used.
-
- So, actually, ¼ of a plane is used, which equals ± 16 kB. The bytes are all over
- a plane, with gaps of three bytes between them. As the planes and offsets
- within planes are automatically selected, we can't use the gaps for any other
- data. Thus, in order to get more than one display page, we must get rid of the
- gaps between the data (or, make them smaller) !
-
-
- ──────═ Chain4, Odd/Even, Linear ═──────────────────────────────────────────────
-
- When the standard BIOS mode is invoked, the chain4 mode is used. Chain4
- mode is explained above. There is the odd/even mode too, where there's also a
- sort of automatic selection of the plane and the offset within the plane. In
- odd/even mode, the lowest bit (LSB) of the offset address together with the page
- bit in the miscellaneous register of the graphics controller is used to
- determine the plane and offset in a kind of similar way as chain4 does that.
- Odd/even mode is not interesting enough to describe here in detail.
-
- As we want to address all of the 256 kB memory of the VGA card, we are not going
- to use the chain4 mode, nor the odd/even mode. We are going to set the VGA card
- to use a sort of linear mode, so we can address every single byte in a plane.
- That will give us access to 256 kB memory. While we are able to address all
- memory, we can then use four different display pages (at a resolution of
- 320x200).
-
-
- ──────═ Double-word, word, byte ═───────────────────────────────────────────────
-
- In BIOS mode, double-word mode is set. This means, for each information byte,
- there are four bytes to be read (two bytes is a word, four bytes is a
- double-word). The VGA card has the opportunity to use one of its three modes:
- Double-word mode, word mode and byte mode. In odd/even mode, word mode should be
- used. For our purposes (four display pages), byte mode should be used, as the
- bytes in the planes will succeed each other, with no gaps.
-
- In short: if double-word mode is set, there are four bytes to read each time one
- information byte is wanted. In word mode, there's need to read two bytes of
- which one is containing real information. In byte mode, one byte needs to be
- read as each separate byte contains information.
-
- As a nasty result (sometimes handy), we will have to tell the VGA to which plane
- we will write, because the offset no longer gets shifted to determine the plane
- and offset within the plane to write to.
-
- Sometimes this comes in handy, because you can specify more than one plane to
- write to. You can, at utmost, set four pixels at the same time to the same
- color, by selecting all planes for writing and writing a byte to an offset.
- Think about this when you're starting to write code to quickly fill areas on
- your screen, for example polygons. With a simple stosb, you can set 4 pixels at
- one time, with a simple stosw you then can set 8 pixels to the same color at
- once. Or better: on a 386 or higher, you can use stosd. With stosd, you can set
- 16 pixels at once. Now, isn't that fast ?
-
- To give you more grip on this, I'll exercise the extended ASCII charset again:
-
- Plane 3 ┌01234567─────────────────────────────────────────────────────┐
- (11b) │37 │
- │ │
- │
- Plane 2 ┌01234567─────────────────────────────────────────────────────┐ │
- (10b) │26 │ │
- │ │ │
- │ │
- Plane 1 ┌01234567─────────────────────────────────────────────────────┐ │ │
- (01b) │15 │ │ │
- │ │ │ │
- │ │
- Plane 0 ┌01234567─────────────────────────────────────────────────────┐ │ │
- (00b) │04 │ │ │
- │ │ │ │
- │ │ │
- │ │ │
- │ │ │
- │ │
- │ │
- │ │
- Real plane dividing in the memory of the VGA (unchained mode, byte mode)
-
- As you see, one offset now denotes four pixels. As mentioned before, you'll have
- to select which planes to write to before setting a pixel.
-
-
- ──────═ Four different pages ═──────────────────────────────────────────────────
-
- Now, we have room for four different pages, we can also select them, but how to
- display each page ?
-
- There are two registers, which together hold the offset in the video area to
- begin displaying at. As each screen is 320x200 big, it needs 64 kB.
- 64 kB is divided over four planes per screen, so a page needs 64000 / 4 = 16000
- offsets for being set-up. The first page starts at offset 0000h, the second at
- 4000h, the third at 8000h and the fourth at 0c000h.
-
- To accommodate this for your set pixel routine, you can add the offset value
- divided by 10h to your segment address, so you don't have to bother about the
- starting offset anymore. You simply set your segment to 0a000h for page 0,
- to 0a400h for page 1, to 0a800h for page 2 and 0ac00h for page three.
- Then, offsets for a page are valid from 0000h to 3e80h.
-
-
- ──────═ Writing to or reading from one of the pages ═───────────────────────────
-
- Writing to a plane is done by first selecting the plane(s) to which to write,
- and then writing a byte to a chosen offset. You can select the plane by using
- the map mask register of the sequencer controller. It is build as follows:
-
- 7 6 5 4 3 2 1 0
- ┌───┬───┬───┬───┬───┬───┬───┬───┐
- │ │ │ │ │ │
- └───┴───┴───┴───┴───┴───┴───┴───┘
- │ │ │ │ │ │
- └───────────┤ │ │ │ └── 0: No access to plane 0
- │ │ │ │ 1: Access to plane 0
- │ │ │ └────── 0: No access to plane 1
- │ │ │ 1: Access to plane 1
- │ │ └────────── 0: No access to plane 2
- │ │ 1: Access to plane 2
- │ └────────────── 0: No access to plane 3
- │ 1: Access to plane 3
- └────────────────── Not used (0)
-
- For reading operations, the read map select register of the graphics controller
- must be changed. This register's layout is:
-
- 7 6 5 4 3 2 1 0
- ┌───┬───┬───┬───┬───┬───┬───┬───┐
- │ │ │
- └───┴───┴───┴───┴───┴───┴───┴───┘
- │ │ │ │
- └───────────────────┤ └───┴── Number of plane to read from
- │
- └────────── Not used (0)
-
-
- ──────═ Displaying different pages ═────────────────────────────────────────────
-
- To display one of the pages, you must set the offset of a page in the two
- registers called Start Address High and Start Address Low of the CRT controller.
- The high byte of the offset is placed in the start address high register,
- the low byte in the start address low register.
-
- You can write to another page than you're showing on the screen, using the
- technique described above. With that in mind, you can do page-flipping (i.e.
- draw something on one page, while displaying the other and then swapping them by
- displaying the one you were drawing on and the one you were showing and do it
- all again with the swapped pages) and hereby eliminating the flicker or vertical
- retrace which is often annoying our presentation. Note that this manner is a
- whole lot faster than copying 64 kB each time!
-
-
- ──────═ 320x400x256 ═───────────────────────────────────────────────────────────
-
- Well, where is that 400 pixels y resolution I promised you ?
- This one is really unexpected (well, I mentioned it at the start of this
- trainer): on the VGA card, there actually isn't a 200 y-resolution available.
- Instead, to keep the addressing as simple as possible AND providing a 256 color
- mode within the 256 kB boundary, the makers of the VGA card have come up with,
- well, logic, but unexpected scheme. By the way, this is also the reason why the
- pixels in 320x200x256 mode look so, like squares (■■ ;)). The lines displayed
- from the memory are just being doubled as they are displayed on the screen.
- So, one line really occupies two lines on the screen. With this solution, the
- memory can contain only 200 lines, but the screen will display 400 lines.
-
- Now we've unchained the planes, and are addressing them linear, we can set the
- VGA to display 400 lines very simple.
-
- The maximum scanline register of the CRT controller is build in this manner:
-
- 7 6 5 4 3 2 1 0
- ┌───┬───┬───┬───┬───┬───┬───┬───┐
- │ │ │ │ │
- └───┴───┴───┴───┴───┴───┴───┴───┘
- │ │ │ │ │
- │ │ │ └───────────────┴── (Times-1) to copy a line on the screen
- │ │ │
- │ │ └────────────────────── EGA: No function
- │ │ VGA: Bit 9 of start vertical blanking register
- │ └────────────────────────── EGA: No function
- │ VGA: Bit 9 of line compare register
- └────────────────────────────── EGA: No function
- VGA: 200 points doubling mode
-
- Bits 0-4: Times-1 to copy a line. If, for example, these have the value 5,
- all lines will be displayed four times, bringing the real
- displayed lines to 200 / 4 = 50 lines.
- Bit 5: Bit 9 of the start vertical blanking register
- Bit 6: Bit 9 of the line compare register
- Bit 7: 0 = line doubling off
- 1 = line doubling on
-
-
- Now, two pages are left. One starting at 0a000h:0000h and the other at
- 0a000h:8000h. Or, with the accommodation: 0a000h:0000h and 0a800h:0000h.
-
-
- ──────═ Used registers ═────────────────────────────────────────────────────────
-
- When switching over to xmode from within BIOS mode 13h, some of the VGA
- registers must be re-programmed. The registers used are:
-
- From the CRT controller (controls the Cathode Ray Tube, or monitor):
- - Maximum scanline register (9h)
- - Start address high byte (0ch)
- - Start address low byte (0dh)
- - Underline location register (14h)
- - Mode control register (17h)
-
- From the sequencer controller (controls the way memory is being displayed):
- - Map mask register (2h)
- - Memory mode register (4h)
-
- From the graphics controller (controls reading/writing to VGA memory):
- - Read map select register (4h)
- - Graphics mode register (5h)
- - Miscellaneous register (6h)
-
- The CRT controller is accessed through port 3d4h and 3d5h (mono: 3b4h and 3b5h).
- The sequencer controller is accessed through ports 3c4h and 3c5h.
- The graphics controller is accessed through ports 3ceh and 3cfh.
-
-
- ┌──────────────────────────────────────────────────────────────────────────────┐
- │░▒▓█ BIOS MODE 13h -> 320x400x256 █▓▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
- └──────────────────────────────────────────────────────────────────────────────┘
-
- Follows: a complete step-by-step description of switching to the xmode,
- using ASM code to help you implementing:
-
- In the code, I use macro's for the ease. I don't have to re-type each block of
- statements (which reduces the errors). A macro is called by just typing its
- name. If there are parameters valid for a macro, you must specify it/them behind
- the macro's name, separated by ",".
- You'll see what I'm trying to say when you see the source code hereafter.
- Consider the following macro's:
-
- Select MACRO Controller,Register
- mov dx,controller ; Select address register
- mov al,register ; to put register index number
- out dx,al
- inc dx ; Select data register
- in al,dx ; Input current value to AL
- ENDM
-
- Other MACRO Register
- dec dx ; Select address register
- mov al,register ; to put register index number
- out dx,al
- inc dx ; Select data register
- in al,dx ; Input current value to AL
- ENDM
-
- Put MACRO
- out dx,al ; Save value of AL to register
- ENDM
-
-
-
- To start, change to BIOS mode 13h using sub-function 0h of int 10h:
-
- mov ax,13h
- int 10h
-
- Then, change the memory mode register so that the chain4 as well as the odd/even
- mode is disabled, but preserve the lowest two bits, coz' they are not of our
- concern:
-
- select seq_c,memory_mode
- and al,00000011b ; Clear & preserve lowest 2 bits
- or al,00000100b ; Chain4 & Odd/Even mode off
- put
-
- Change the graphics mode register so that a linear mode is being used by
- clearing bit number 4, but preserve the rest of the bits. Again, they are not of
- our concern:
-
- select gfx_c,graphics_mode ; Set linear mode
- and al,11101111b
- put
-
- We do the same thing in the miscellaneous register of the graphics controller,
- but we clear bit number 1 instead of bit 4:
-
- other miscellaneous ; Set linear mode
- and al,11111101b
- put
-
- Remember, we had to change from double-word mode to byte mode by turning of
- double-word and word mode. We'll do this by clearing bit number 6 of the
- underline location register of the CRT controller for the double-word mode, and
- by setting bit number 6 of the mode control register of the same controller:
-
- select crt_c,underline_loc ; Double-word mode off
- and al,10111111b
- put
-
- other mode_control ; Word mode off, byte mode on
- or al,01000000b
- put
-
- And last but not least, we turn off line doubling and line copying to get 400
- lines on a screen by clearing bit number 7 and bit number 3 to 0 of the maximum
- scanline register of the CRT controller:
-
- other max_scan_line ; 320x400x256
- and al,01110000b
- put
-
- With the map mask register of the sequencer controller, we can control which
- planes to write to. As we want to clear all planes, we select all planes for
- writing by setting bit number 3 to 0:
-
- select seq_c,map_mask ; All planes on for writing
- or al,00001111b
- put
-
- Finally, we're clearing all planes by writing a zero word 32768 times (setting
- all the 256 kB to zero) to the VGA segment 0a000h (thus, starting at page 0):
-
- mov ax,0a000h ; Set ES to VGA segment (0a000h)
- mov es,ax
- xor di,di ; and DI to offset 0000h
- mov cx,08000h ; The number of words is 32768
- xor ax,ax ; Put a zero word 32768 times to
- rep stosw ; ES:DI
-
-
-
- That's all there is !
-
- Now, you're ready to get exciting and beautiful graphics in a higher resolution,
- with still 256 colors, and two pages, for use with page-flipping !!
-
-
- ┌──────────────────────────────────────────────────────────────────────────────┐
- │░▒▓█ DISCLAIMER █▓▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
- └──────────────────────────────────────────────────────────────────────────────┘
-
- Well, as usual, the author of this text is not responsible for any damage caused
- by the use or misuse of this text, bla, bla, har, har, nag, nag, etc.......
-
-
- ┌──────────────────────────────────────────────────────────────────────────────┐
- │░▒▓█ EPILOGUE ;) █▓▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
- └──────────────────────────────────────────────────────────────────────────────┘
-
- Hey, when you do any productions, using above explanation or something,
- greet me !! I'd like that.....
-
- You can usually contact me at EightBall, +31-546-829093, just write a private
- message to The Bitripper. If that doesn't work, Ash soon has got his board up
- and running again, so you can find me there also. I'll see you around...
-
- Happy coding!
-
- - The Bitripper -
-
-
- ┌──────────────────────────────────────────────────────────────────────────────┐
- │░▒▓█ GREETS █▓▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
- └──────────────────────────────────────────────────────────────────────────────┘
-
- Greets go out to (alphabetical order):
-
- Ash - Hiya!
- Evil - Long time no see (hear no Evil, see no Evil ;))
- HeXoN - Having a good time?
- Lord Addu - Hear you've got another job?
- R.L. - Don't know your current handle
-
- and the rest of the people I forgot to mention here...